#ifndef __PCI_H__
#define __PCI_H__
#define PCI_STATUS    0x06  /* 16 bits */

#define PCI_ANY_ID	(~0)

/*
 * Under PCI, each device has 256 bytes of configuration address space,
 * of which the first 64 bytes are standardized as follows:
 */
#define PCI_VENDOR_ID   0x00  /* 16 bits */
#define PCI_DEVICE_ID   0x02  /* 16 bits */
#define PCI_COMMAND   0x04  /* 16 bits */
#define  PCI_COMMAND_IO   0x1 /* Enable response in I/O space */
#define  PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define  PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
#define  PCI_COMMAND_SPECIAL  0x8 /* Enable response to special cycles */
#define  PCI_COMMAND_INVALIDATE 0x10  /* Use memory write and invalidate */
#define  PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
#define  PCI_COMMAND_PARITY 0x40  /* Enable parity checking */
#define  PCI_COMMAND_WAIT   0x80  /* Enable address/data stepping */
#define  PCI_COMMAND_SERR 0x100 /* Enable SERR */
#define  PCI_COMMAND_FAST_BACK  0x200 /* Enable back-to-back writes */
#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */

#define PCI_EXP_FLAGS   2 /* Capabilities register */
#define PCI_EXP_FLAGS_TYPE  0x00f0  /* Device/Port type */
#define PCI_EXP_FLAGS_SLOT  0x0100  /* Slot implemented */
#define PCI_EXP_SLTCAP    20  /* Slot Capabilities */
#define  PCI_EXP_SLTCAP_ABP 0x00000001 /* Attention Button Present */
#define  PCI_EXP_SLTCAP_PCP 0x00000002 /* Power Controller Present */
#define  PCI_EXP_SLTCAP_MRLSP 0x00000004 /* MRL Sensor Present */
#define  PCI_EXP_SLTCAP_AIP 0x00000008 /* Attention Indicator Present */
#define  PCI_EXP_SLTCAP_PIP 0x00000010 /* Power Indicator Present */
#define  PCI_EXP_SLTCAP_HPS 0x00000020 /* Hot-Plug Surprise */
#define  PCI_EXP_SLTCAP_HPC 0x00000040 /* Hot-Plug Capable */
#define  PCI_EXP_SLTCAP_SPLV  0x00007f80 /* Slot Power Limit Value */
#define  PCI_EXP_SLTCAP_SPLS  0x00018000 /* Slot Power Limit Scale */
#define  PCI_EXP_SLTCAP_EIP 0x00020000 /* Electromechanical Interlock Present */
#define  PCI_EXP_SLTCAP_NCCS  0x00040000 /* No Command Completed Support */
#define  PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */

#define PCI_INTERRUPT_LINE  0x3c  /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d  /* 8 bits */

#define PCI_BASE_ADDRESS_0  0x10  /* 32 bits */
#define PCI_BASE_ADDRESS_1  0x14  /* 32 bits [htype 0,1 only] */
#define PCI_BASE_ADDRESS_2  0x18  /* 32 bits [htype 0 only] */
#define PCI_BASE_ADDRESS_3  0x1c  /* 32 bits */
#define PCI_BASE_ADDRESS_4  0x20  /* 32 bits */
#define PCI_BASE_ADDRESS_5  0x24  /* 32 bits */
#define  PCI_BASE_ADDRESS_SPACE_IO  0x01
#define  PCI_BASE_ADDRESS_MEM_PREFETCH  0x08  /* prefetchable? */
#define  PCI_BASE_ADDRESS_MEM_MASK  (~0x0fUL)
#define  PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
#define  PCI_BASE_ADDRESS_MEM_TYPE_64 0x04  /* 64 bit address */
#define  PCI_BASE_ADDRESS_SPACE   0x01  /* 0 = memory, 1 = I/O */

#define PCI_ROM_ADDRESS   0x30  /* Bits 31..11 are address, 10..1 reserved */
#define  PCI_ROM_ADDRESS_ENABLE 0x01
#define PCI_ROM_ADDRESS_MASK  (~0x7ffUL)

#define PCI_STATUS    0x06  /* 16 bits */
#define  PCI_STATUS_CAP_LIST  0x10  /* Support Capability List */

#define PCI_HEADER_TYPE   0x0e  /* 8 bits */
#define  PCI_HEADER_TYPE_NORMAL   0
#define  PCI_HEADER_TYPE_BRIDGE   1
#define  PCI_HEADER_TYPE_CARDBUS  2

#define PCI_CACHE_LINE_SIZE 0x0c  /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d  /* 8 bits */
#define PCI_HEADER_TYPE   0x0e  /* 8 bits */
#define  PCI_HEADER_TYPE_NORMAL   0
#define  PCI_HEADER_TYPE_BRIDGE   1
#define  PCI_HEADER_TYPE_CARDBUS  2

#define PCI_CAPABILITY_LIST 0x34  /* Offset of first capability list entry */
#define PCI_CB_CAPABILITY_LIST  0x14

/* Capability lists */

#define PCI_CAP_LIST_ID   0 /* Capability ID */
#define  PCI_CAP_ID_PM    0x01  /* Power Management */
#define  PCI_CAP_ID_AGP   0x02  /* Accelerated Graphics Port */
#define  PCI_CAP_ID_VPD   0x03  /* Vital Product Data */
#define  PCI_CAP_ID_SLOTID  0x04  /* Slot Identification */
#define  PCI_CAP_ID_MSI   0x05  /* Message Signalled Interrupts */
#define  PCI_CAP_ID_CHSWP 0x06  /* CompactPCI HotSwap */
#define  PCI_CAP_ID_PCIX  0x07  /* PCI-X */
#define  PCI_CAP_ID_HT    0x08  /* HyperTransport */
#define  PCI_CAP_ID_VNDR  0x09  /* Vendor specific */
#define  PCI_CAP_ID_DBG   0x0A  /* Debug port */
#define  PCI_CAP_ID_CCRC  0x0B  /* CompactPCI Central Resource Control */
#define  PCI_CAP_ID_SHPC  0x0C  /* PCI Standard Hot-Plug Controller */
#define  PCI_CAP_ID_SSVID 0x0D  /* Bridge subsystem vendor/device ID */
#define  PCI_CAP_ID_AGP3  0x0E  /* AGP Target PCI-PCI bridge */
#define  PCI_CAP_ID_EXP   0x10  /* PCI Express */
#define  PCI_CAP_ID_MSIX  0x11  /* MSI-X */
#define  PCI_CAP_ID_AF    0x13  /* PCI Advanced Features */
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
#define PCI_CAP_FLAGS   2 /* Capability defined flags (16 bits) */
#define PCI_CAP_SIZEOF    4

#define PCI_CLASS_DEVICE  0x0a  /* Device class */
#define PCI_CLASS_BRIDGE_HOST   0x0600
#define PCI_CLASS_DISPLAY_VGA   0x0300
#define PCI_CLASS_REVISION  0x08  /* High 24 bits are class, low 8 revision */
#define PCI_REVISION_ID   0x08  /* Revision ID */
#define PCI_CLASS_PROG    0x09  /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE  0x0a  /* Device class */

#define PCI_CB_SUBSYSTEM_VENDOR_ID  0x40
#define PCI_CB_SUBSYSTEM_ID   0x42
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#define PCI_SUBSYSTEM_ID  0x2e

#define PCI_ROM_ADDRESS1  0x38  /* Same as PCI_ROM_ADDRESS, but for htype 1 */

#define PCI_BASE_CLASS_STORAGE    0x01
#define PCI_CLASS_STORAGE_SCSI    0x0100
#define PCI_CLASS_STORAGE_IDE   0x0101
#define PCI_CLASS_STORAGE_FLOPPY  0x0102
#define PCI_CLASS_STORAGE_IPI   0x0103
#define PCI_CLASS_STORAGE_RAID    0x0104
#define PCI_CLASS_STORAGE_SATA    0x0106
#define PCI_CLASS_STORAGE_SATA_AHCI 0x010601
#define PCI_CLASS_STORAGE_SAS   0x0107
#define PCI_CLASS_STORAGE_OTHER   0x0180
#define PCI_CLASS_BRIDGE_CARDBUS  0x0607

#define PCI_SSVID_VENDOR_ID     4 /* PCI-Bridge subsystem vendor id register */
#define PCI_SSVID_DEVICE_ID     6 /* PCI-Bridge subsystem device id register */

#define PCI_CLASS_BRIDGE_PCI    0x0604

#define PCI_VENDOR_ID   0x00  /* 16 bits */

#define PCI_VENDOR_ID_INTEL   0x8086
#define PCI_VENDOR_ID_COMPAQ    0x0e11

#define PCI_CLASS_BRIDGE_HOST   0x0600
#define  PCI_CAP_ID_PCIX  0x07  /* PCI-X */
#define PCI_X_STATUS    4 /* PCI-X capabilities */
#define  PCI_X_STATUS_266MHZ  0x40000000  /* 266 MHz capable */
#define  PCI_X_STATUS_533MHZ  0x80000000  /* 533 MHz capable */

#define PCI_CFG_SPACE_SIZE  256
#define PCI_CFG_SPACE_EXP_SIZE  4096

/*    
 * The PCI interface treats multi-function devices as independent
 * devices.  The slot/function address of each device is encoded
 * in a single byte as follows:
 *
 *  7:3 = slot
 *  2:0 = function
 */ 
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define PCI_SLOT(devfn)   (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn)   ((devfn) & 0x07)

/*
 * Error values that may be returned by PCI functions.
 */
#define PCIBIOS_SUCCESSFUL    0x00
#define PCIBIOS_FUNC_NOT_SUPPORTED  0x81
#define PCIBIOS_BAD_VENDOR_ID   0x83
#define PCIBIOS_DEVICE_NOT_FOUND  0x86
#define PCIBIOS_BAD_REGISTER_NUMBER 0x87
#define PCIBIOS_SET_FAILED    0x88
#define PCIBIOS_BUFFER_TOO_SMALL  0x89

enum pci_fixup_pass {
  pci_fixup_early,  /* Before probing BARs */
  pci_fixup_header, /* After reading configuration header */
  pci_fixup_final,  /* Final phase of device fixups */
  pci_fixup_enable, /* pci_enable_device() time */
  pci_fixup_resume, /* pci_device_resume() */
  pci_fixup_suspend,  /* pci_device_suspend */
  pci_fixup_resume_early, /* pci_device_resume_early() */
}; 

enum pci_bar_type {
  pci_bar_unknown,  /* Standard PCI BAR probe */ 
  pci_bar_io,   /* An io port BAR */
  pci_bar_mem32,    /* A 32-bit memory BAR */
  pci_bar_mem64,    /* A 64-bit memory BAR */
};  

/*
 *  For PCI devices, the region numbers are assigned this way:
 */
enum {
  /* #0-5: standard PCI resources */
  PCI_STD_RESOURCES,
  PCI_STD_RESOURCE_END = 5,

  /* #6: expansion ROM resource */
  PCI_ROM_RESOURCE,

  /* device specific resources */
#ifdef CONFIG_PCI_IOV
  PCI_IOV_RESOURCES,
  PCI_IOV_RESOURCE_END = PCI_IOV_RESOURCES + PCI_SRIOV_NUM_BARS - 1,
#endif

  /* resources assigned to buses behind the bridge */
#define PCI_BRIDGE_RESOURCE_NUM 4

  PCI_BRIDGE_RESOURCES,
  PCI_BRIDGE_RESOURCE_END = PCI_BRIDGE_RESOURCES +
          PCI_BRIDGE_RESOURCE_NUM - 1,

  /* total resources associated with a PCI device */
  PCI_NUM_RESOURCES,

  /* preserve this for compatibility */
  DEVICE_COUNT_RESOURCE
};

/*
 * Resources are tree-like, allowing
 * nesting etc..
 */
#define IORESOURCE_TYPE_BITS  0x00000f00  /* Resource type */
#define IORESOURCE_IO   0x00000100
#define IORESOURCE_MEM    0x00000200
#define IORESOURCE_IRQ    0x00000400
#define IORESOURCE_DMA    0x00000800
#define IORESOURCE_MEM_64 0x00100000

#define IORESOURCE_PREFETCH 0x00001000  /* No side effects */
#define IORESOURCE_SIZEALIGN  0x00020000  /* size indicates alignment */
#define IORESOURCE_STARTALIGN 0x00040000  /* start field is alignment */
#define IORESOURCE_READONLY 0x00002000
#define IORESOURCE_CACHEABLE  0x00004000

/* PCI ROM control bits (IORESOURCE_BITS) */
#define IORESOURCE_ROM_ENABLE   (1<<0)  /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
#define IORESOURCE_ROM_SHADOW   (1<<1)  /* ROM is copy at C000:0 */
#define IORESOURCE_ROM_COPY   (1<<2)  /* ROM is alloc'd copy, resource field overlaid */
#define IORESOURCE_ROM_BIOS_COPY  (1<<3)  /* ROM is BIOS copy, resource field overlaid */

/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
#define IORESOURCE_PCI_FIXED    (1<<4)  /* Do not move resource */

#define PCI_DEVICE_ID_INTEL_EESSC	0x0008
#define PCI_DEVICE_ID_INTEL_PXHD_0	0x0320
#define PCI_DEVICE_ID_INTEL_PXHD_1	0x0321
#define PCI_DEVICE_ID_INTEL_PXH_0	0x0329
#define PCI_DEVICE_ID_INTEL_PXH_1	0x032A
#define PCI_DEVICE_ID_INTEL_PXHV	0x032C
#define PCI_DEVICE_ID_INTEL_80332_0	0x0330
#define PCI_DEVICE_ID_INTEL_80332_1	0x0332
#define PCI_DEVICE_ID_INTEL_80333_0	0x0370
#define PCI_DEVICE_ID_INTEL_80333_1	0x0372
#define PCI_DEVICE_ID_INTEL_82375	0x0482
#define PCI_DEVICE_ID_INTEL_82424	0x0483
#define PCI_DEVICE_ID_INTEL_82378	0x0484
#define PCI_DEVICE_ID_INTEL_I960	0x0960
#define PCI_DEVICE_ID_INTEL_I960RM	0x0962
#define PCI_DEVICE_ID_INTEL_8257X_SOL	0x1062
#define PCI_DEVICE_ID_INTEL_82573E_SOL	0x1085
#define PCI_DEVICE_ID_INTEL_82573L_SOL	0x108F
#define PCI_DEVICE_ID_INTEL_82815_MC	0x1130
#define PCI_DEVICE_ID_INTEL_82815_CGC	0x1132
#define PCI_DEVICE_ID_INTEL_82092AA_0	0x1221
#define PCI_DEVICE_ID_INTEL_7505_0	0x2550  
#define PCI_DEVICE_ID_INTEL_7205_0	0x255d
#define PCI_DEVICE_ID_INTEL_82437	0x122d
#define PCI_DEVICE_ID_INTEL_82371FB_0	0x122e
#define PCI_DEVICE_ID_INTEL_82371FB_1	0x1230
#define PCI_DEVICE_ID_INTEL_82371MX	0x1234
#define PCI_DEVICE_ID_INTEL_82441	0x1237
#define PCI_DEVICE_ID_INTEL_82380FB	0x124b
#define PCI_DEVICE_ID_INTEL_82439	0x1250
#define PCI_DEVICE_ID_INTEL_80960_RP	0x1960
#define PCI_DEVICE_ID_INTEL_82840_HB	0x1a21
#define PCI_DEVICE_ID_INTEL_82845_HB	0x1a30
#define PCI_DEVICE_ID_INTEL_IOAT	0x1a38
#define PCI_DEVICE_ID_INTEL_82801AA_0	0x2410
#define PCI_DEVICE_ID_INTEL_82801AA_1	0x2411
#define PCI_DEVICE_ID_INTEL_82801AA_3	0x2413
#define PCI_DEVICE_ID_INTEL_82801AA_5	0x2415
#define PCI_DEVICE_ID_INTEL_82801AA_6	0x2416
#define PCI_DEVICE_ID_INTEL_82801AA_8	0x2418
#define PCI_DEVICE_ID_INTEL_82801AB_0	0x2420
#define PCI_DEVICE_ID_INTEL_82801AB_1	0x2421
#define PCI_DEVICE_ID_INTEL_82801AB_3	0x2423
#define PCI_DEVICE_ID_INTEL_82801AB_5	0x2425
#define PCI_DEVICE_ID_INTEL_82801AB_6	0x2426
#define PCI_DEVICE_ID_INTEL_82801AB_8	0x2428
#define PCI_DEVICE_ID_INTEL_82801BA_0	0x2440
#define PCI_DEVICE_ID_INTEL_82801BA_2	0x2443
#define PCI_DEVICE_ID_INTEL_82801BA_4	0x2445
#define PCI_DEVICE_ID_INTEL_82801BA_6	0x2448
#define PCI_DEVICE_ID_INTEL_82801BA_8	0x244a
#define PCI_DEVICE_ID_INTEL_82801BA_9	0x244b
#define PCI_DEVICE_ID_INTEL_82801BA_10	0x244c
#define PCI_DEVICE_ID_INTEL_82801BA_11	0x244e
#define PCI_DEVICE_ID_INTEL_82801E_0	0x2450
#define PCI_DEVICE_ID_INTEL_82801E_11	0x245b
#define PCI_DEVICE_ID_INTEL_82801CA_0	0x2480
#define PCI_DEVICE_ID_INTEL_82801CA_3	0x2483
#define PCI_DEVICE_ID_INTEL_82801CA_5	0x2485
#define PCI_DEVICE_ID_INTEL_82801CA_6	0x2486
#define PCI_DEVICE_ID_INTEL_82801CA_10	0x248a
#define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
#define PCI_DEVICE_ID_INTEL_82801CA_12	0x248c
#define PCI_DEVICE_ID_INTEL_82801DB_0	0x24c0
#define PCI_DEVICE_ID_INTEL_82801DB_1	0x24c1
#define PCI_DEVICE_ID_INTEL_82801DB_2	0x24c2
#define PCI_DEVICE_ID_INTEL_82801DB_3	0x24c3
#define PCI_DEVICE_ID_INTEL_82801DB_5	0x24c5
#define PCI_DEVICE_ID_INTEL_82801DB_6	0x24c6
#define PCI_DEVICE_ID_INTEL_82801DB_9	0x24c9
#define PCI_DEVICE_ID_INTEL_82801DB_10	0x24ca
#define PCI_DEVICE_ID_INTEL_82801DB_11	0x24cb
#define PCI_DEVICE_ID_INTEL_82801DB_12  0x24cc
#define PCI_DEVICE_ID_INTEL_82801EB_0	0x24d0
#define PCI_DEVICE_ID_INTEL_82801EB_1	0x24d1
#define PCI_DEVICE_ID_INTEL_82801EB_3	0x24d3
#define PCI_DEVICE_ID_INTEL_82801EB_5	0x24d5
#define PCI_DEVICE_ID_INTEL_82801EB_6	0x24d6
#define PCI_DEVICE_ID_INTEL_82801EB_11	0x24db
#define PCI_DEVICE_ID_INTEL_82801EB_12	0x24dc
#define PCI_DEVICE_ID_INTEL_82801EB_13	0x24dd
#define PCI_DEVICE_ID_INTEL_ESB_1	0x25a1
#define PCI_DEVICE_ID_INTEL_ESB_2	0x25a2
#define PCI_DEVICE_ID_INTEL_ESB_4	0x25a4
#define PCI_DEVICE_ID_INTEL_ESB_5	0x25a6
#define PCI_DEVICE_ID_INTEL_ESB_9	0x25ab
#define PCI_DEVICE_ID_INTEL_ESB_10	0x25ac
#define PCI_DEVICE_ID_INTEL_82820_HB	0x2500
#define PCI_DEVICE_ID_INTEL_82820_UP_HB	0x2501
#define PCI_DEVICE_ID_INTEL_82850_HB	0x2530
#define PCI_DEVICE_ID_INTEL_82860_HB	0x2531
#define PCI_DEVICE_ID_INTEL_E7501_MCH	0x254c
#define PCI_DEVICE_ID_INTEL_82845G_HB	0x2560
#define PCI_DEVICE_ID_INTEL_82845G_IG	0x2562
#define PCI_DEVICE_ID_INTEL_82865_HB	0x2570
#define PCI_DEVICE_ID_INTEL_82865_IG	0x2572
#define PCI_DEVICE_ID_INTEL_82875_HB	0x2578
#define PCI_DEVICE_ID_INTEL_82915G_HB	0x2580
#define PCI_DEVICE_ID_INTEL_82915G_IG	0x2582
#define PCI_DEVICE_ID_INTEL_82915GM_HB	0x2590
#define PCI_DEVICE_ID_INTEL_82915GM_IG	0x2592
#define PCI_DEVICE_ID_INTEL_5000_ERR	0x25F0
#define PCI_DEVICE_ID_INTEL_5000_FBD0	0x25F5
#define PCI_DEVICE_ID_INTEL_5000_FBD1	0x25F6
#define PCI_DEVICE_ID_INTEL_82945G_HB	0x2770
#define PCI_DEVICE_ID_INTEL_82945G_IG	0x2772
#define PCI_DEVICE_ID_INTEL_3000_HB	0x2778
#define PCI_DEVICE_ID_INTEL_82945GM_HB	0x27A0
#define PCI_DEVICE_ID_INTEL_82945GM_IG	0x27A2
#define PCI_DEVICE_ID_INTEL_ICH6_0	0x2640
#define PCI_DEVICE_ID_INTEL_ICH6_1	0x2641
#define PCI_DEVICE_ID_INTEL_ICH6_2	0x2642
#define PCI_DEVICE_ID_INTEL_ICH6_16	0x266a
#define PCI_DEVICE_ID_INTEL_ICH6_17	0x266d
#define PCI_DEVICE_ID_INTEL_ICH6_18	0x266e
#define PCI_DEVICE_ID_INTEL_ICH6_19	0x266f
#define PCI_DEVICE_ID_INTEL_ESB2_0	0x2670
#define PCI_DEVICE_ID_INTEL_ESB2_14	0x2698
#define PCI_DEVICE_ID_INTEL_ESB2_17	0x269b
#define PCI_DEVICE_ID_INTEL_ESB2_18	0x269e
#define PCI_DEVICE_ID_INTEL_ICH7_0	0x27b8
#define PCI_DEVICE_ID_INTEL_ICH7_1	0x27b9
#define PCI_DEVICE_ID_INTEL_ICH7_30	0x27b0
#define PCI_DEVICE_ID_INTEL_TGP_LPC	0x27bc
#define PCI_DEVICE_ID_INTEL_ICH7_31	0x27bd
#define PCI_DEVICE_ID_INTEL_ICH7_17	0x27da
#define PCI_DEVICE_ID_INTEL_ICH7_19	0x27dd
#define PCI_DEVICE_ID_INTEL_ICH7_20	0x27de
#define PCI_DEVICE_ID_INTEL_ICH7_21	0x27df
#define PCI_DEVICE_ID_INTEL_ICH8_0	0x2810
#define PCI_DEVICE_ID_INTEL_ICH8_1	0x2811
#define PCI_DEVICE_ID_INTEL_ICH8_2	0x2812
#define PCI_DEVICE_ID_INTEL_ICH8_3	0x2814
#define PCI_DEVICE_ID_INTEL_ICH8_4	0x2815
#define PCI_DEVICE_ID_INTEL_ICH8_5	0x283e
#define PCI_DEVICE_ID_INTEL_ICH8_6	0x2850
#define PCI_DEVICE_ID_INTEL_ICH9_0	0x2910
#define PCI_DEVICE_ID_INTEL_ICH9_1	0x2917
#define PCI_DEVICE_ID_INTEL_ICH9_2	0x2912
#define PCI_DEVICE_ID_INTEL_ICH9_3	0x2913
#define PCI_DEVICE_ID_INTEL_ICH9_4	0x2914
#define PCI_DEVICE_ID_INTEL_ICH9_5	0x2919
#define PCI_DEVICE_ID_INTEL_ICH9_6	0x2930
#define PCI_DEVICE_ID_INTEL_ICH9_7	0x2916
#define PCI_DEVICE_ID_INTEL_ICH9_8	0x2918
#define PCI_DEVICE_ID_INTEL_82855PM_HB	0x3340
#define PCI_DEVICE_ID_INTEL_IOAT_TBG4	0x3429
#define PCI_DEVICE_ID_INTEL_IOAT_TBG5	0x342a
#define PCI_DEVICE_ID_INTEL_IOAT_TBG6	0x342b
#define PCI_DEVICE_ID_INTEL_IOAT_TBG7	0x342c
#define PCI_DEVICE_ID_INTEL_IOAT_TBG0	0x3430
#define PCI_DEVICE_ID_INTEL_IOAT_TBG1	0x3431
#define PCI_DEVICE_ID_INTEL_IOAT_TBG2	0x3432
#define PCI_DEVICE_ID_INTEL_IOAT_TBG3	0x3433
#define PCI_DEVICE_ID_INTEL_82830_HB	0x3575
#define PCI_DEVICE_ID_INTEL_82830_CGC	0x3577
#define PCI_DEVICE_ID_INTEL_82854_HB	0x358c
#define PCI_DEVICE_ID_INTEL_82854_IG	0x358e
#define PCI_DEVICE_ID_INTEL_82855GM_HB	0x3580
#define PCI_DEVICE_ID_INTEL_82855GM_IG	0x3582
#define PCI_DEVICE_ID_INTEL_E7520_MCH	0x3590
#define PCI_DEVICE_ID_INTEL_E7320_MCH	0x3592
#define PCI_DEVICE_ID_INTEL_MCH_PA	0x3595
#define PCI_DEVICE_ID_INTEL_MCH_PA1	0x3596
#define PCI_DEVICE_ID_INTEL_MCH_PB	0x3597
#define PCI_DEVICE_ID_INTEL_MCH_PB1	0x3598
#define PCI_DEVICE_ID_INTEL_MCH_PC	0x3599
#define PCI_DEVICE_ID_INTEL_MCH_PC1	0x359a
#define PCI_DEVICE_ID_INTEL_E7525_MCH	0x359e
#define PCI_DEVICE_ID_INTEL_IOAT_CNB	0x360b
#define PCI_DEVICE_ID_INTEL_FBD_CNB	0x360c
#define PCI_DEVICE_ID_INTEL_IOAT_JSF0	0x3710
#define PCI_DEVICE_ID_INTEL_IOAT_JSF1	0x3711
#define PCI_DEVICE_ID_INTEL_IOAT_JSF2	0x3712
#define PCI_DEVICE_ID_INTEL_IOAT_JSF3	0x3713
#define PCI_DEVICE_ID_INTEL_IOAT_JSF4	0x3714
#define PCI_DEVICE_ID_INTEL_IOAT_JSF5	0x3715
#define PCI_DEVICE_ID_INTEL_IOAT_JSF6	0x3716
#define PCI_DEVICE_ID_INTEL_IOAT_JSF7	0x3717
#define PCI_DEVICE_ID_INTEL_IOAT_JSF8	0x3718
#define PCI_DEVICE_ID_INTEL_IOAT_JSF9	0x3719
#define PCI_DEVICE_ID_INTEL_ICH10_0	0x3a14
#define PCI_DEVICE_ID_INTEL_ICH10_1	0x3a16
#define PCI_DEVICE_ID_INTEL_ICH10_2	0x3a18
#define PCI_DEVICE_ID_INTEL_ICH10_3	0x3a1a
#define PCI_DEVICE_ID_INTEL_ICH10_4	0x3a30
#define PCI_DEVICE_ID_INTEL_ICH10_5	0x3a60
#define PCI_DEVICE_ID_INTEL_PCH_LPC_MIN	0x3b00
#define PCI_DEVICE_ID_INTEL_PCH_LPC_MAX	0x3b1f
#define PCI_DEVICE_ID_INTEL_PCH_SMBUS	0x3b30
#define PCI_DEVICE_ID_INTEL_IOAT_SNB	0x402f
#define PCI_DEVICE_ID_INTEL_5100_16	0x65f0
#define PCI_DEVICE_ID_INTEL_5100_21	0x65f5
#define PCI_DEVICE_ID_INTEL_5100_22	0x65f6
#define PCI_DEVICE_ID_INTEL_5400_ERR	0x4030
#define PCI_DEVICE_ID_INTEL_5400_FBD0	0x4035
#define PCI_DEVICE_ID_INTEL_5400_FBD1	0x4036
#define PCI_DEVICE_ID_INTEL_IOAT_SCNB	0x65ff
#define PCI_DEVICE_ID_INTEL_TOLAPAI_0	0x5031
#define PCI_DEVICE_ID_INTEL_TOLAPAI_1	0x5032
#define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
#define PCI_DEVICE_ID_INTEL_82371SB_2	0x7020
#define PCI_DEVICE_ID_INTEL_82437VX	0x7030
#define PCI_DEVICE_ID_INTEL_82439TX	0x7100
#define PCI_DEVICE_ID_INTEL_82371AB_0	0x7110
#define PCI_DEVICE_ID_INTEL_82371AB	0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_2	0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3	0x7113
#define PCI_DEVICE_ID_INTEL_82810_MC1	0x7120
#define PCI_DEVICE_ID_INTEL_82810_IG1	0x7121
#define PCI_DEVICE_ID_INTEL_82810_MC3	0x7122
#define PCI_DEVICE_ID_INTEL_82810_IG3	0x7123
#define PCI_DEVICE_ID_INTEL_82810E_MC	0x7124
#define PCI_DEVICE_ID_INTEL_82810E_IG	0x7125
#define PCI_DEVICE_ID_INTEL_82443LX_0	0x7180
#define PCI_DEVICE_ID_INTEL_82443LX_1	0x7181
#define PCI_DEVICE_ID_INTEL_82443BX_0	0x7190
#define PCI_DEVICE_ID_INTEL_82443BX_1	0x7191
#define PCI_DEVICE_ID_INTEL_82443BX_2	0x7192
#define PCI_DEVICE_ID_INTEL_440MX	0x7195
#define PCI_DEVICE_ID_INTEL_440MX_6	0x7196
#define PCI_DEVICE_ID_INTEL_82443MX_0	0x7198
#define PCI_DEVICE_ID_INTEL_82443MX_1	0x7199
#define PCI_DEVICE_ID_INTEL_82443MX_3	0x719b
#define PCI_DEVICE_ID_INTEL_82443GX_0	0x71a0
#define PCI_DEVICE_ID_INTEL_82443GX_2	0x71a2
#define PCI_DEVICE_ID_INTEL_82372FB_1	0x7601
#define PCI_DEVICE_ID_INTEL_SCH_LPC	0x8119
#define PCI_DEVICE_ID_INTEL_SCH_IDE	0x811a
#define PCI_DEVICE_ID_INTEL_82454GX	0x84c4
#define PCI_DEVICE_ID_INTEL_82450GX	0x84c5
#define PCI_DEVICE_ID_INTEL_82451NX	0x84ca
#define PCI_DEVICE_ID_INTEL_82454NX     0x84cb
#define PCI_DEVICE_ID_INTEL_84460GX	0x84ea
#define PCI_DEVICE_ID_INTEL_IXP4XX	0x8500
#define PCI_DEVICE_ID_INTEL_IXP2800	0x9004
#define PCI_DEVICE_ID_INTEL_S21152BB	0xb152

/* these helpers provide future and backwards compatibility
 * for accessing popular PCI BAR info */
#define pci_resource_start(dev, bar)  ((dev)->resource[(bar)].start)
#define pci_resource_end(dev, bar)  ((dev)->resource[(bar)].end)
#define pci_resource_flags(dev, bar)  ((dev)->resource[(bar)].flags)
#define pci_resource_len(dev,bar) \
  ((pci_resource_start((dev), (bar)) == 0 &&  \
    pci_resource_end((dev), (bar)) ==   \
    pci_resource_start((dev), (bar))) ? 0 : \
              \
   (pci_resource_end((dev), (bar)) -    \
    pci_resource_start((dev), (bar)) + 1))

struct resource {
  unsigned int start;
  unsigned int end;
  const char *name;
  unsigned long flags;
  struct resource *parent, *sibling, *child;
};

/*
struct resource_list {
  struct resource_list *next;
  struct resource *res;
  struct pci_dev *dev;
};
*/

struct pci_device_id {
  u32_t vendor, device;   /* Vendor and device ID or PCI_ANY_ID*/
  u32_t subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
  u32_t class, class_mask;  /* (class,subclass,prog-if) triplet */
  unsigned long driver_data; /* Data private to the driver */
};

struct pci_bus {
	struct list_struct devices;	
	struct pci_bus *parent,*children,*sibling;
	unsigned char busnr;
	unsigned short domain;
	char bus_name[41];
};

struct pci_device {
	struct list_struct dev_node;
	struct pci_bus *bus;	
	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
	u8_t hdr_type;
	unsigned int devfn;
	unsigned short vendor;
	unsigned short device;
	unsigned short subsystem_vendor;
	unsigned short subsystem_device;
	unsigned int irq;
	unsigned int class;
	unsigned int is_pcie;
	unsigned int transparent;
	unsigned int is_hotplug_bridge;
	u64_t dma_mask;
	u8_t 	pcie_type;
	u8_t  pcie_cap;
	u8_t 	pin;
	u8_t  revision;
	int cfg_size; /* size of configuration space */
	int multifunction;
	int is_busmaster;
	int rom_base_reg;
	char dev_name[50];
	void *driver_data;
};

extern struct pci_device * find_dev(unsigned short domain,unsigned char busnr,unsigned int devfn);
extern struct pci_device * find_dev_by_vendor(unsigned short vendor,unsigned short device);
extern int pci_read_config_byte(struct pci_bus *bus,unsigned int devfn,int pos,u8_t *value);
extern int pci_read_config_word(struct pci_bus *bus,unsigned int devfn,int pos,u16_t *value);
extern int pci_read_config_dword(struct pci_bus *bus,unsigned int devfn,int pos,u32_t *value);
extern int pci_write_config_byte(struct pci_bus *bus,unsigned int devfn,int pos,u8_t value);
extern int pci_write_config_word(struct pci_bus *bus,unsigned int devfn,int pos,u16_t value);
#endif /* __PCI_H__ */
